<script setup lang="ts">
import type { mastodon } from 'masto'

definePageMeta({
  middleware: 'auth',
})

const { t } = useI18n()

const client = useMastoClient()

const paginator = client.v1.lists.list()

useHydratedHead({
  title: () => t('nav.lists'),
})

const paginatorRef = ref()
const inputRef = ref<HTMLInputElement>()
const actionError = ref<string | undefined>(undefined)
const busy = ref<boolean>(false)
const createText = ref('')
const enableSubmit = computed(() => createText.value.length > 0)

async function createList() {
  if (busy.value || !enableSubmit.value)
    return

  busy.value = true
  actionError.value = undefined
  await nextTick()
  try {
    const newEntry = await client.v1.lists.create({
      title: createText.value,
    })
    paginatorRef.value?.createEntry(newEntry)
    createText.value = ''
  }
  catch (err) {
    console.error(err)
    actionError.value = (err as Error).message
    nextTick(() => {
      inputRef.value?.focus()
    })
  }
  finally {
    busy.value = false
  }
}

function clearError(focusBtn: boolean) {
  actionError.value = undefined
  if (focusBtn) {
    nextTick(() => {
      inputRef.value?.focus()
    })
  }
}

function updateEntry(list: mastodon.v1.List) {
  paginatorRef.value?.updateEntry(list)
}
function removeEntry(id: string) {
  paginatorRef.value?.removeEntry(id)
}

onDeactivated(() => clearError(false))
</script>

<template>
  <MainContent>
    <template #title>
      <NuxtLink to="/lists" timeline-title-style flex items-center gap-2 @click="$scrollToTop">
        <div i-ri:list-check />
        <span text-lg font-bold>{{ t('nav.lists') }}</span>
      </NuxtLink>
    </template>
    <slot>
      <CommonPaginator ref="paginatorRef" :paginator="paginator">
        <template #default="{ item }">
          <ListEntry
            :model-value="item"
            @update:model-value="updateEntry"
            @list-removed="removeEntry"
          />
        </template>
        <template #done>
          <form
            border="t base"
            p-4 w-full
            flex="~ wrap" relative gap-3
            :aria-describedby="actionError ? 'create-list-error' : undefined"
            :class="actionError ? 'border border-base border-rounded rounded-be-is-0 rounded-be-ie-0 border-b-unset border-$c-danger-active' : null"
            @submit.prevent="createList"
          >
            <div
              bg-base border="~ base" flex-1 h10 ps-1 pe-4 rounded-2 w-full flex="~ row"
              items-center relative focus-within:box-shadow-outline gap-3
            >
              <input
                ref="inputRef"
                v-model="createText"
                bg-transparent
                outline="focus:none"
                px-4
                pb="1px"
                flex-1
                placeholder-text-secondary
                :placeholder="$t('list.list_title_placeholder')"
                @keypress.enter="createList"
              >
            </div>
            <div flex="~ col" gap-y-4 gap-x-2 sm="~ justify-between flex-row">
              <button flex="~ row" gap-x-2 items-center btn-solid :disabled="!enableSubmit || busy">
                <span v-if="busy" aria-hidden="true" block animate animate-spin preserve-3d class="rtl-flip">
                  <span block i-ri:loader-2-fill aria-hidden="true" />
                </span>
                <span v-else aria-hidden="true" block i-material-symbols:playlist-add-rounded class="rtl-flip" />
                {{ $t('list.create') }}
              </button>
            </div>
          </form>
          <CommonErrorMessage
            v-if="actionError"
            id="create-list-error"
            described-by="create-list-failed"
            class="rounded-bs-is-0 rounded-bs-ie-0 border-t-dashed m-b-2"
          >
            <header id="create-list-failed" flex justify-between>
              <div flex items-center gap-x-2 font-bold>
                <div aria-hidden="true" i-ri:error-warning-fill />
                <p>{{ $t('list.error') }}</p>
              </div>
              <CommonTooltip placement="bottom" :content="$t('list.clear_error')">
                <button
                  flex rounded-4 p1 hover:bg-active cursor-pointer transition-100 :aria-label="$t('list.clear_error')"
                  @click="clearError(true)"
                >
                  <span aria-hidden="true" w="1.75em" h="1.75em" i-ri:close-line />
                </button>
              </CommonTooltip>
            </header>
            <ol ps-2 sm:ps-1>
              <li flex="~ col sm:row" gap-y-1 sm:gap-x-2>
                <strong sr-only>{{ $t('list.error_prefix') }}</strong>
                <span>{{ actionError }}</span>
              </li>
            </ol>
          </CommonErrorMessage>
        </template>
      </CommonPaginator>
    </slot>
  </MainContent>
</template>
